<!--
TODO for later:
* allow limiting resizing to x or y direction
-->
<div ref:cont style="position:relative;">
    <div
        id="iframe-wrapper"
        class="{loading?'loading':''} {resizable?'resizable' :''} {resizing?'resizing' :''}"
        style="width:{width}px;height:{height}px; overflow:visible;"
    >
        <iframe
            title="chart-preview"
            ref:iframe
            src="{url}"
            on:load="iframeLoaded(event)"
            id="iframe-vis"
            allowfullscreen
            webkitallowfullscreen
            mozallowfullscreen
            oallowfullscreen
            msallowfullscreen
        ></iframe>
        {#if resizable}
        <div ref="resizer" on:mousedown="dragStart(event)" class="resizer resizer-both">
            <i class="fa fa-arrows-h"></i>
        </div>
        {/if}
    </div>

    <div id="notifications"></div>
</div>

<style>
    #iframe-wrapper {
        margin: 20px auto 0;
    }
    #iframe-wrapper.loading {
        opacity: 1;
    }
    #iframe-wrapper:before {
        pointer-events: none;
        display: block;
        content: '';
        position: absolute;
        top: -1px;
        right: -1px;
        bottom: -1px;
        left: -1px;
        background: #f9f9f9;
        background: #f3f3f3;
        opacity: 0;
        transition: opacity 0.6s ease;
    }
    #iframe-wrapper.loading:before {
        opacity: 0.95;
    }
    #iframe-wrapper.loading:after {
        content: 'loading...';
        display: block;
        color: #999;
        position: absolute;
        top: 50%;
        right: 0;
        bottom: 0;
        font-size: 20px;
        left: 0;
        text-align: center;
        line-height: 0;
    }
    #iframe-wrapper.loading iframe {
        /*filter: blur(5px);*/
    }
    .resizing iframe {
        pointer-events: none;
    }
</style>

<script>
    // import updateChartDescription from './lib/updateChartDescription';
    import updateChartAttributes from './lib/updateChartAttributes';

    let iframe;
    let preview;
    let startX;
    let startY;
    let startWidth;
    let startHeight;

    export default {
        data() {
            return {
                src: false,
                loading: true,
                // resize logic
                width: 500,
                height: 500,
                resizable: true,
                resizing: false,
                // inline editing
                editable: true
            };
        },
        computed: {
            url({ $id, src }) {
                // eslint-disable-next-line
                return src ? src : $id ? `/chart/${$id}/preview` : '';
            }
        },
        methods: {
            iframeLoaded() {
                const { editable } = this.get();
                if (editable) {
                    this.getContext((win, doc) => {
                        activateInlineEditing(doc, this.store);
                    });
                }
                this.fire('iframeLoaded');
            },
            saved() {
                const win = iframe.contentWindow;
                if (win.__dw && win.__dw.saved) {
                    win.__dw.saved();
                }
            },
            getContext(callback) {
                const win = this.refs.iframe.contentWindow;
                const doc = this.refs.iframe.contentDocument;

                if (!win.__dw || !win.__dw.vis) {
                    return setTimeout(() => {
                        this.getContext(callback);
                    }, 200);
                }
                setTimeout(() => {
                    callback(win, doc);
                }, 1000);
            },
            forceRender() {
                const state = this.store.serialize();
                updateChartAttributes({
                    iframe: this.refs.iframe,
                    attrs: state,
                    forceRender: true,
                    callback: () => {
                        this.set({ loading: false });
                    }
                });
            },
            reload() {
                this.refs.iframe.contentWindow.location.reload();
            },
            dragStart(event) {
                startX = event.clientX;
                startY = event.clientY;
                startWidth = this.get().width;
                startHeight = this.get().height;
                this.set({ resizing: true });
                this.fire('beforeResize');
                window.document.addEventListener('mousemove', doDrag);
                window.document.addEventListener('mouseup', stopDrag);
            }
        },
        oncreate() {
            iframe = this.refs.iframe;
            preview = this;

            // 5. Resize when chart wants to resize itself
            window.addEventListener('message', e => {
                var message = e.data;
                const { resizing } = this.get();
                if (resizing) return;

                if (typeof message['datawrapper-height'] !== 'undefined') {
                    var h;

                    for (var chartId in message['datawrapper-height']) {
                        h = message['datawrapper-height'][chartId];
                    }

                    this.set({ height: h });
                }
            });

            const chart = this.store;

            chart.on('state', ({ current }) => {
                if (current.passiveMode) {
                    // no update of chart in iframe when in passiveMode
                    return;
                }

                const attrs = chart.serialize();
                updateChartAttributes({
                    // eslint-disable-next-line
                    iframe: this.refs.iframe,
                    attrs,
                    callback: () => {
                        this.set({ loading: false });
                    }
                });
                if (chart.getMetadata('data.json')) {
                    // chart._rawData = JSON.stringify(chart.get('dataset'));
                    // updateChartData({
                    //     iframe: this.refs.iframe,
                    //     data: chart._rawData
                    // });
                }
            });
        },
        // eslint-disable-next-line
        onupdate({ changed, current }) {
            // sync embed height and width
            if (changed.width) {
                this.store.setMetadata('publish.embed-width', current.width);
            }
            if (changed.height) {
                this.store.setMetadata('publish.embed-height', current.height);
            }
        }
    };

    function doDrag(event) {
        preview.set({
            width: startWidth + (event.clientX - startX) * 2,
            height: startHeight + event.clientY - startY
        });
        event.preventDefault();
        return false;
    }

    function stopDrag() {
        window.document.removeEventListener('mousemove', doDrag);
        window.document.removeEventListener('mouseup', stopDrag);
        preview.set({ resizing: false });
        const { width, height } = preview.get();
        const bbox = preview.refs.iframe.contentDocument.querySelector('.dw-chart-body').getBoundingClientRect();
        const maxH = preview.refs.iframe.contentWindow.dw.utils.getMaxChartHeight();
        const [chartWidth, chartHeight] = [bbox.width, maxH];
        preview.fire('resize', { width, height, chartWidth, chartHeight });
    }

    function activateInlineEditing(doc, chart) {
        makeElementEditable({
            el: doc.querySelector('.chart-title'),
            onchange(lbl) {
                chart.set({ passiveMode: true });
                chart.set({ title: lbl });
                chart.set({ passiveMode: false });
            }
        });

        makeElementEditable({
            el: doc.querySelector('.chart-intro'),
            onchange: sync('describe.intro')
        });

        makeElementEditable({
            el: doc.querySelector('.dw-chart-notes'),
            onchange: sync('annotate.notes')
        });

        function sync(key) {
            return function(txt) {
                chart.set({ passiveMode: true });
                chart.setMetadata(key, txt);
                chart.set({ passiveMode: false });
            };
        }

        function makeElementEditable({ el, onchange }) {
            if (!el) return;
            let lastValue = false;

            el.setAttribute('contenteditable', true);

            el.addEventListener('focus', () => {
                // save old value for ESC key
                lastValue = el.innerHTML;
            });

            el.addEventListener('keyup', evt => {
                if (evt.keyCode === 27) {
                    evt.preventDefault();
                    // escape key, revert last value
                    el.innerHTML = lastValue;
                    el.blur();
                }
                onchange(el.innerHTML.replace(/(<br>)+$/g, ''));
            });
        }
    }
</script>
